package com.nil.codegen.utils;

import com.nil.codegen.bean.DsInfo;
import com.nil.codegen.enums.DriverTypeEnum;
import com.nil.codegen.exception.BusinessException;

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtil {


    /**
     * 测试连接
     */
    public static Connection testConnection(DsInfo dsInfo) {

        Connection connection = null;
        DriverTypeEnum driverType = dsInfo.getDriverType();
        if (driverType == null) {
            throw new BusinessException("未知的驱动类型");
        }
        Properties props = new Properties();
        props.setProperty("user", dsInfo.getUsername());
        props.setProperty("password", dsInfo.getPassword());
        props.setProperty("characterEncoding", "utf-8");
        String url = getConnUrl(dsInfo);
        Driver driver = null;
        if (driverType != DriverTypeEnum.PGSQL) {
            try {
                driver = loadDriverFromRemoteJar(dsInfo.getPackageUrl(), driverType.getPgName());
            } catch (Exception e) {
                throw new RuntimeException("加载驱动包程序出现异常, " + e.getMessage());
            }
        }
        if (null != driver) {
            try {
                connection = driver.connect(url, props);
            } catch (SQLException e) {
                throw new RuntimeException("数据库连接失败, " + e.getMessage());
            }
        }

        return connection;
    }

    /**
     * 获取连接URL
     */
    public static String getConnUrl(DsInfo dsInfo) {
        DriverTypeEnum driverType = dsInfo.getDriverType();
        if (driverType == null) {
            throw new BusinessException("未知的驱动类型");
        }
        String host = dsInfo.getHost();
        Integer port = dsInfo.getPort();
        String database = dsInfo.getDbName();
        String schema = dsInfo.getSchema();
        StringBuilder url = new StringBuilder();
        switch (driverType) {
            case DM:
                url.append("jdbc:dm://dm_dw?dm_dw=(").append(host)
                        .append(":").append(port.toString()).append(")")
                        .append("&loginMode=1&useUnicode=true&characterEncoding=utf8")
                        .append("&schema=").append(schema);
                break;
            case MYSQL:
                url.append("jdbc:mysql://").append(host)
                        .append(":").append(port.toString()).append("/")
                        .append(database);
                break;
            case PGSQL:
                url.append("jdbc:postgresql://").append(host).append(port).append("/").append(database);
                break;
            case ORACLE:
                url.append("jdbc:oracle:thin:@").append(host).append(":").append(port).append(":").append(schema);
                break;

        }
        dsInfo.setUrl(url.toString());
        return url.toString();
    }

    /**
     * 加载远程驱动包
     * @param remoteJarUrl 远程 jar的访问链接
     * @param className    远程 jar 中的全类名
     */
    private static Driver loadDriverFromRemoteJar(String remoteJarUrl, String className) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        URL jarUrl = new URL(remoteJarUrl);
        URLClassLoader remoteClassLoader = new URLClassLoader(new URL[]{jarUrl}, ClassLoader.getSystemClassLoader());
        Class<?> driverClass = Class.forName(className, true, remoteClassLoader);
        return (Driver) driverClass.newInstance();
    }


}
